pike > development tips
development tips
Created by hww3. Last updated by hww3,
11 years ago. Version #3.
Module (ie, Java "static") methods in a CMOD
You can have INIT, EXIT and PIKEFUN blocks outside of a PIKECLASS directive. Because modules are already instantiated as objects, this allows your module to have functions as well as classes.
Calling pike functions from within C/CMOD code
Here's some code for calling (whether they're written in c or pike) functions from your C language module code. Remember that you can create objects this way because create is called implicitly, just ask for the class name you want to instantiate:
// this code works for a function that takes one argument.
// you'll have to modify it to get it to understand multiple args.
// args are at top of stack
// look up the function
push_text( "Sql.sql_result");
SAFE_APPLY_MASTER("resolv", 1 );
// method is at top of the stack, we want the arg on top
stack_swap();
// arg is at top, function is 1 down from the top
apply_svalue( Pike_sp-2, 1 );
// result is at top of the stack, function is still one down
// and we want to pop it.
stack_swap();
pop_stack();
To run the function "query" in the current object with one arg, already on the stack:
// get the identifier for the member we want to call
int i;
i=find_identifier("query", Pike_fp->current_object->prog);
// now call the method with the context of the current object.
apply_low(Pike_fp->current_object, i, 1);
Another option:
/* push arguments on stack */
apply(Pike_fp->current_object, "the method", number_of_args);
The return value will be on the stack, don't forget to
pop it after you are done with it.
Working with references
Pike utilizes garbage collection and reference counting to handle memory management of pike data objects (strings, arrays, objects, etc). When writing C/CMOD code, you need to tell pike that you explicitly want to keep data around once it passes out of your function, along with the corresponding process of telling pike that you're done with the object afterward. Pike provides methods for doing this (though some methods will add references automatically).
add_ref(svalue val) is used to add a reference to a variable.
free_string(pike_string val) and its corresponding friends is used to subtract references and will free the variable if there are no more references to that variable. The name can be confusing but it's best to think of it from the standpoint of your code not knowing whether other code is using your variable. You're just saying that "it's ok by me if you want to free this value." Pike will actually do that when everone who said they wanted to keep it no longer want the value.
Working with arguments
Pike_sp is your key to working with the Pike stack. The top of the stack (ie the last argument passed to your function) is Pike_sp[-1], and the bottom of the stack (or the first argument) is Pike_sp[-args]. Therefore, to get the
n~~th argument, where 1 is the first argument, is Pike_sp[-args + n -1].
Alternately, you can use
get_all_args() to check to make sure you have the proper number and type of arguments, and place them into variables. If your needs are not terribly complex (I'm pretty sure that it doesn't handle variable argument types or varargs), this might be a good option.
If your function receives incorrect arguments, instead of using Pike_error, use the following:
for too few arguments, use:
SIMPLE_TOO_FEW_ARGS_ERROR("myfunction",1);
for bad arguments, use:
SIMPLE_BAD_ARG_ERROR("myfunction", 1, "array|mapping|whatever");
Looping through Mappings
The
NEW_MAPPING_LOOP macro allows you to loop through all elements in a mapping. Note that the keypair name (~~k) is required and is hard coded.
INT32 e;
struct keypair *k;
NEW_MAPPING_LOOP(mapping->data) {
k->ind
k->val // both are svalues
}
Debugging
courtesy of grubba
If you have the broken pike running in a gdb, you can try running
as well as
The latter should also work when examining a core dump.
If it isn't possible to call gdb_backtraces(), you'll probably want to examine the stack frames by hand. The top-most frame is available as
p *Pike_interpreter_pointer->frame_pointer
Not categorized
|
RSS Feed
| BackLinks